package org.jeecg.modules.purchase.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.exception.ServiceException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.modules.purchase.entity.PurchaseStock;
import org.jeecg.modules.purchase.entity.PurchaseStockCheck;
import org.jeecg.modules.purchase.entity.PurchaseStockCheckDetail;
import org.jeecg.modules.purchase.mapper.PurchaseStockCheckDetailMapper;
import org.jeecg.modules.purchase.mapper.PurchaseStockCheckMapper;
import org.jeecg.modules.purchase.service.IPurchaseStockCheckService;
import org.jeecg.modules.purchase.service.IPurchaseStockService;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.List;
import java.util.Collection;

/**
 * @Description: 库存盘点
 * @Author: jeecg-boot
 * @Date:   2022-11-15
 * @Version: V1.0
 */
@Service
public class PurchaseStockCheckServiceImpl extends ServiceImpl<PurchaseStockCheckMapper, PurchaseStockCheck> implements IPurchaseStockCheckService {

	private final String CODE = "StockCheckCodeRule";
	@Autowired
	private PurchaseStockCheckMapper purchaseStockCheckMapper;
	@Autowired
	private PurchaseStockCheckDetailMapper purchaseStockCheckDetailMapper;

	@Resource
	private IPurchaseStockService purchaseStockService;

	@Autowired
	private ISysBaseAPI sysBaseAPI;
	
	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveMain(PurchaseStockCheck purchaseStockCheck, List<PurchaseStockCheckDetail> purchaseStockCheckDetailList) {
		//如果编码为空,就重新请求编码
		if(StringUtils.isBlank(purchaseStockCheck.getCode())){
			String code = null;
			Result result = sysBaseAPI.executeByRuleCode(CODE,new JSONObject());
			if(result.isSuccess()){
				code = (String)result.getResult();
			}
			purchaseStockCheck.setCode(code);
		}
		purchaseStockCheckMapper.insert(purchaseStockCheck);
		if(purchaseStockCheckDetailList != null && purchaseStockCheckDetailList.size() > 0) {
			for(PurchaseStockCheckDetail entity : purchaseStockCheckDetailList) {
				if (entity.getCheckNumber() == null)
					continue;
				if (entity.getCheckNumber().compareTo(BigDecimal.ZERO) < 0){
					throw new ServiceException("盘点数量不能为负数");
				}
				// 获取库存
				LambdaQueryWrapper<PurchaseStock> wrapper = new LambdaQueryWrapper<>();
				wrapper.eq(PurchaseStock::getRepositoryCode, purchaseStockCheck.getRepositoryCode());
				wrapper.eq(PurchaseStock::getGoodsCode, entity.getGoodsCode());
				wrapper.eq(PurchaseStock::getGoodsUnitPrice, entity.getUnitPrice());
				PurchaseStock purchaseStock = purchaseStockService.getOne(wrapper);
				if (ObjectUtil.isEmpty(purchaseStock)){
					throw new ServiceException("库存不存在");
				}
				// 计算盈亏数量
				entity.setProfitLoss(entity.getCheckNumber().subtract(entity.getRepositoryNumber()));
				// 更新库存
				purchaseStock.setTotalNumber(entity.getCheckNumber());
				purchaseStockService.updateById(purchaseStock);
				//外键设置
				entity.setStockCheckId(purchaseStockCheck.getId());
				purchaseStockCheckDetailMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void updateMain(PurchaseStockCheck purchaseStockCheck,List<PurchaseStockCheckDetail> purchaseStockCheckDetailList) {

		// 获取原盘点明细记录
		List<PurchaseStockCheckDetail> oriPurchaseStockCheckDetails = purchaseStockCheckDetailMapper.selectByMainId(purchaseStockCheck.getId());
		// 获取原盘点记录
		PurchaseStockCheck oriPurchaseStockCheck = this.getById(purchaseStockCheck.getId());
		// 更新库存盘点记录
		purchaseStockCheckMapper.updateById(purchaseStockCheck);
		//删除子表数据
		purchaseStockCheckDetailMapper.deleteByMainId(purchaseStockCheck.getId());
		// 1.修改盘点盈亏数量
		if(purchaseStockCheckDetailList!=null && purchaseStockCheckDetailList.size()>0) {
			for(PurchaseStockCheckDetail entity:purchaseStockCheckDetailList) {
				// 获取库存
				LambdaQueryWrapper<PurchaseStock> wrapper = new LambdaQueryWrapper<>();
				wrapper.eq(PurchaseStock::getRepositoryCode, purchaseStockCheck.getRepositoryCode());
				wrapper.eq(PurchaseStock::getGoodsCode, entity.getGoodsCode());
				wrapper.eq(PurchaseStock::getGoodsUnitPrice, entity.getUnitPrice());
				PurchaseStock purchaseStock = purchaseStockService.getOne(wrapper);
				if (entity.getCheckNumber() == null || entity.getCheckNumber().compareTo(BigDecimal.ZERO) < 0){
					throw new ServiceException("盘点数量不能为负数");
				}
				if (ObjectUtil.isEmpty(purchaseStock)){
					throw new ServiceException("库存不存在");
				}
				// 重新计算盈亏数量，修改库存
				entity.setProfitLoss(entity.getCheckNumber().subtract(entity.getRepositoryNumber()));
				purchaseStock.setTotalNumber(entity.getCheckNumber());
				purchaseStockService.updateById(purchaseStock);

				//外键设置
				entity.setStockCheckId(purchaseStockCheck.getId());
				//2.子表数据重新插入
				purchaseStockCheckDetailMapper.insert(entity);
			}
		}
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delMain(String id) {
		purchaseStockCheckDetailMapper.deleteByMainId(id);
		purchaseStockCheckMapper.deleteById(id);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void delBatchMain(Collection<? extends Serializable> idList) {
		for(Serializable id:idList) {
			purchaseStockCheckDetailMapper.deleteByMainId(id.toString());
			purchaseStockCheckMapper.deleteById(id);
		}
	}

	private PurchaseStock createPurchaseStock(PurchaseStockCheckDetail entity, String repositoryCode, String repositoryName){
		PurchaseStock purchaseStock = new PurchaseStock();
		purchaseStock.setRepositoryName(repositoryName);
		purchaseStock.setRepositoryCode(repositoryCode);
		purchaseStock.setGoodsName(entity.getGoodsName());
		purchaseStock.setGoodsTypeCode(entity.getGoodsTypeCode());
		purchaseStock.setGoodsCode(entity.getGoodsCode());
		purchaseStock.setBrand(entity.getBrand());
		purchaseStock.setGoodsSize(entity.getSize());
		purchaseStock.setGoodsUnit(entity.getUnit());
		purchaseStock.setGoodsUnitPrice(entity.getUnitPrice());
		return purchaseStock;
	}
	
}
